package com.huilian.iotbox.data.service.impl;

import com.huilian.iotbox.data.dao.LawHolidayDao;
import com.huilian.iotbox.data.enums.LawHolidayEnum;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.service.LawHolidayService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author lizhiquan
 * @CreateDate: 2021-05-03 11:54
 * @Description:
 */
@Service
public class LawHolidayServiceImpl implements LawHolidayService {

    @Resource
    private RedisTemplate<String, Serializable> redisCacheTemplate;
    @Resource
    private LawHolidayDao lawHolidayDao;

    /**
     * @description 判断是否是休息日（包含法定节假日和不需要补班的周末）
     **/
    @Override
    public boolean isHoliday(String calendar) throws Exception {
        // 首先法定节假日必定是休息日
        if (this.isLawHoliday(calendar)) {
            return true;
        }
        // 排除法定节假日外的非周末必定是工作日
        if (!this.isWeekends(calendar)) {
            return false;
        }
        // 所有周末中只有非补班的才是休息日
        if (this.isExtraWorkday(calendar)) {
            return false;
        }
        return true;
    }

    /**
     * @description 判断是否是法定假日
     **/
    @Override
    public boolean isLawHoliday(String calendar) throws Exception {
        // 法律规定的放假日期
        List<String> lawHolidays = this.findLawHolidayList(LawHolidayEnum.LAW_HOLIDAY.getCode());

        if (lawHolidays.contains(calendar)) {
            return true;
        }
        return false;
    }

    /**
     * @description 判断是否是需要额外补班的周末
     **/
    @Override
    public boolean isExtraWorkday(String calendar) throws Exception {
        // 由于放假需要额外工作的周末
        List<String> extraWorkdays = this.findLawHolidayList(LawHolidayEnum.EXTRA_WORKDAY.getCode());

        if (extraWorkdays.contains(calendar)) {
            return true;
        }
        return false;
    }

    /**
     * @description 判断是否是周末
     **/
    @Override
    public boolean isWeekends(String calendar) throws Exception {
        // 先将字符串类型的日期转换为Calendar类型
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(calendar);
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        if (ca.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
                || ca.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    /**
     * @description 校验字符串是否为指定的日期格式, 含逻辑严格校验, 2007/02/30返回false
     **/
    private boolean isValidDate(String str) {
        boolean convertSuccess = true;
        // 指定日期格式为四位年/两位月份/两位日期，注意yyyy-MM-dd区分大小写；
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            // 设置lenient为false.
            // 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }
        return convertSuccess;
    }

    @Override
    public List findLawHolidayList(Integer type) {
        String key = RedisKey.HOLIDAY_ + type;
        List<String> dateList = (List<String>) redisCacheTemplate.opsForValue().get(key);
        if (dateList == null || dateList.size() == 0) {
            dateList = lawHolidayDao.findLawHolidayList(type);
            if (dateList != null && dateList.size() > 0) {
                redisCacheTemplate.opsForValue().set(key, (Serializable) dateList);
            }
        }
        return dateList;
    }
}
